<template>
    <div class="image-categories">
      <!-- 顶部工具栏 -->
      <div class="toolbar">
        <div class="left-actions">
          <button class="action-btn primary" @click="showUploadDialog = true">
            <i class="icon">📤</i>
            上传图片
          </button>
          <button class="action-btn" @click="showNewCategoryDialog = true">
            <i class="icon">📁</i>
            新建分类
          </button>
          <button class="action-btn" @click="exportDataset">
            <i class="icon">📦</i>
            导出数据集
          </button>
          <div class="search-box">
            <input 
              type="text" 
              v-model="searchCategory"
              placeholder="搜索分类..."
            >
          </div>
        </div>
      </div>
  
      <!-- 主内容区 -->
      <div class="main-content">
        <!-- 左侧分类列表 -->
        <div class="categories-nav">
          <div class="nav-header">分类列表</div>
          <div class="nav-list">
            <div class="nav-item"
                 :class="{ active: currentCategory === null }"
                 @click="selectCategory(null)">
              <i class="icon">📁</i>
              <span class="item-name">未分类</span>
              <span class="item-count">{{ getUncategorizedCount() }}</span>
            </div>
            <div v-for="category in categories"
                 :key="category.id"
                 class="nav-item"
                 :class="{ active: currentCategory?.id === category.id }"
                 @click="selectCategory(category)">
              <i class="icon">📁</i>
              <span class="item-name">{{ category.name }}</span>
              <span class="item-count">{{ getCategoryImageCount(category.id) }}</span>
              <button v-if="canDelete(category)" 
                      class="delete-btn"
                      @click.stop="deleteCategory(category)">
                删除
              </button>
            </div>
          </div>
        </div>
  
        <!-- 右侧图片列表 -->
        <div class="images-container">
          <div class="images-header">
            {{ currentCategory ? currentCategory.name : '未分类' }}
          </div>
          <div class="images-grid">
            <div v-for="image in filteredImages" 
                 :key="image.id" 
                 class="image-item"
                 @click="showUpdateCategoryDialog(image)">
              <div class="image-actions">
                <button class="delete-btn" @click.stop="confirmDelete(image)">
                  <i class="icon">🗑️</i>
                </button>
              </div>
              <img :src="`http://111.229.88.2:8000/uploads/categories/${image.filename.split('/').pop()}`" 
                   :alt="image.filename"
                   @error="handleImageError">
              <div class="image-info">
                <span class="filename">{{ image.filename.split('/').pop() }}</span>
                <span class="category">{{ getCategoryName(image.category_id) }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
  
      <!-- 新建分类对话框 -->
      <div v-if="showNewCategoryDialog" class="dialog-overlay">
        <div class="dialog">
          <h3>新建分类</h3>
          <div class="form-item">
            <label>分类名称</label>
            <input 
              type="text" 
              v-model="newCategoryName"
              placeholder="请输入分类名称"
            >
          </div>
          <div class="form-item">
            <label>分类描述</label>
            <textarea 
              v-model="newCategoryDesc"
              placeholder="请输入分类描述（可选）"
            ></textarea>
          </div>
          <div class="dialog-footer">
            <button class="cancel-btn" @click="showNewCategoryDialog = false">取消</button>
            <button class="confirm-btn" @click="createCategory">确定</button>
          </div>
        </div>
      </div>

      <!-- 修改分类对话框 -->
      <div v-if="showUpdateDialog" class="dialog-overlay">
        <div class="dialog">
          <h3>修改图片分类</h3>
          <div class="form-item">
            <label>选择分类</label>
            <select v-model="selectedUpdateCategoryId">
              <option value="">未分类</option>
              <option v-for="category in categories" 
                      :key="category.id" 
                      :value="category.id">
                {{ category.name }}
              </option>
            </select>
          </div>
          <div class="dialog-footer">
            <button class="cancel-btn" @click="showUpdateDialog = false">取消</button>
            <button class="confirm-btn" @click="handleUpdateCategory">确定</button>
          </div>
        </div>
      </div>

      <!-- 上传图片对话框 -->
      <div v-if="showUploadDialog" class="dialog-overlay">
        <div class="dialog">
          <h3>上传图片</h3>
          <div class="form-item">
            <label>选择分类</label>
            <select v-model="selectedCategoryId">
              <option value="">请选择分类...</option>
              <option v-for="category in categories" 
                      :key="category.id" 
                      :value="category.id">
                {{ category.name }}
              </option>
            </select>
          </div>
          <div class="form-item">
            <label>选择图片</label>
            <ImageManager 
              ref="imageManager"
              type="category"
              :multiple="false"
              @upload-success="handleUploadSuccess"
              @upload-error="handleUploadError"
            />
          </div>
          <div class="dialog-footer">
            <button class="cancel-btn" @click="showUploadDialog = false">取消</button>
          </div>
        </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, computed, onMounted } from 'vue'
  import axios from 'axios'
  import ImageManager from './ImageManager.vue'
  
  const categories = ref([])
  const images = ref([])
  const currentCategory = ref(null)
  const loading = ref(false)
  const error = ref(null)
  const showNewCategoryDialog = ref(false)
  const newCategoryName = ref('')
  const newCategoryDesc = ref('')
  const searchCategory = ref('')
  const showUpdateDialog = ref(false)
  const selectedUpdateCategoryId = ref('')
  const currentEditingImage = ref(null)
  const showUploadDialog = ref(false)
  const selectedCategoryId = ref('')
  
  // 过滤当前分类的图片
  const filteredImages = computed(() => {
    if (!currentCategory.value) {
      // 显示未分类图片
      return images.value.filter(img => !img.category_id)
    }
    return images.value.filter(img => img.category_id === currentCategory.value.id)
  })
  
  // 获取分类的图片数量
  const getCategoryImageCount = (categoryId) => {
    return images.value.filter(img => img.category_id === categoryId).length
  }
  
  // 获取未分类图片数量
  const getUncategorizedCount = () => {
    return images.value.filter(img => !img.category_id).length
  }
  
  // 选择分类
  const selectCategory = (category) => {
    currentCategory.value = category
  }
  
  // 导出数据集
  const exportDataset = async () => {
    try {
      const response = await axios.get('http://111.229.88.2:8000/api/export', {
        params: {
          type: 'category'
        },
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        },
        responseType: 'blob'
      })
      
      const url = window.URL.createObjectURL(new Blob([response.data]))
      const link = document.createElement('a')
      link.href = url
      link.setAttribute('download', 'dataset.zip')
      document.body.appendChild(link)
      link.click()
      link.remove()
      window.URL.revokeObjectURL(url)  // 清理 URL 对象
    } catch (err) {
      console.error('导出失败:', err)
      alert(err.response?.data?.detail || '导出失败')
    }
  }
  
  // 从服务器获取分类列表
  const fetchCategories = async () => {
    loading.value = true
    error.value = null
    try {
      const response = await axios.get('http://111.229.88.2:8000/api/categories', {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      console.log('获取到的分类:', response.data)
      categories.value = response.data
    } catch (err) {
      console.error('获取分类失败:', err)
      error.value = '获取分类列表失败'
    } finally {
      loading.value = false
    }
  }
  
  // 获取图片列表
  const fetchImages = async () => {
    try {
      const response = await axios.get('http://111.229.88.2:8000/api/images', {
        params: {
          type: 'category',
          category_id: currentCategory?.id
        },
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      images.value = response.data
    } catch (error) {
      console.error('获取图片列表失败:', error)
    }
  }
  
  // 创建新分类
  const createCategory = async () => {
    if (!newCategoryName.value.trim()) {
      alert('请输入分类名称')
      return
    }
    
    try {
      console.log('正在创建分类...')
      const response = await axios.post('http://111.229.88.2:8000/api/categories', {
        name: newCategoryName.value.trim(),
        desc: newCategoryDesc.value.trim()
      }, {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      
      console.log('创建分类成功:', response.data)
      categories.value.push(response.data)
      showNewCategoryDialog.value = false
      newCategoryName.value = ''
      newCategoryDesc.value = ''
    } catch (err) {
      console.error('创建分类失败:', err)
      alert('创建分类失败')
    }
  }
  
  // 删除分类
  const deleteCategory = async (category) => {
    if (!confirm('确定要删除这个分类吗？')) return
    
    try {
      await axios.delete(`http://111.229.88.2:8000/api/categories/${category.id}`, {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      
      const index = categories.value.findIndex(c => c.id === category.id)
      if (index > -1) {
        categories.value.splice(index, 1)
      }
      if (currentCategory.value?.id === category.id) {
        currentCategory.value = null
      }
    } catch (err) {
      console.error('删除分类失败:', err)
      alert('删除分类失败')
    }
  }
  
  // 检查是否可以删除分类
  const canDelete = (category) => {
    const username = localStorage.getItem('username')
    return category.created_by === username
  }
  
  // 获取分类名称
  const getCategoryName = (categoryId) => {
    if (!categoryId) return '未分类'
    const category = categories.value.find(c => c.id === categoryId)
    return category ? category.name : '未知分类'
  }
  
  // 显示修改分类对话框
  const showUpdateCategoryDialog = (image) => {
    currentEditingImage.value = image
    selectedUpdateCategoryId.value = image.category_id || ''
    showUpdateDialog.value = true
  }
  
  // 更新图片分类
  const updateImageCategory = async (imageId, categoryId) => {
    try {
      const response = await axios.put(`http://111.229.88.2:8000/api/images/${imageId}/category`, {
        category_id: categoryId || null,
        type: 'category'
      }, {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      
      // 更新本地图片数据
      const index = images.value.findIndex(img => img.id === imageId)
      if (index !== -1) {
        images.value[index].category_id = categoryId || null
      }
    } catch (err) {
      console.error('更新分类失败:', err)
      alert(err.response?.data?.detail || '更新分类失败')
    }
  }
  
  // 处理修改分类对话框的更新
  const handleUpdateCategory = async () => {
    if (!currentEditingImage.value) return
    
    await updateImageCategory(
      currentEditingImage.value.id,
      selectedUpdateCategoryId.value
    )
    
    showUpdateDialog.value = false
    currentEditingImage.value = null
  }
  
  // 确认删除图片
  const confirmDelete = async (image) => {
    if (!confirm(`确定要删除图片 ${image.filename.split('/').pop()} 吗？`)) {
      return
    }
    
    try {
      await axios.delete(`/api/images/${image.id}`, {
        params: { type: 'category' },
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        }
      })
      
      // 从列表中移除
      images.value = images.value.filter(img => img.id !== image.id)
    } catch (err) {
      console.error('删除失败:', err)
      alert('删除失败')
    }
  }
  
  // 处理上传成功
  const handleUploadSuccess = (data) => {
    images.value.unshift(data)
    // 如果选择了分类，更新图片分类
    if (selectedCategoryId.value) {
      updateImageCategory(data.id, selectedCategoryId.value)
    }
    showUploadDialog.value = false
    selectedCategoryId.value = ''  // 清空选择的分类
  }
  
  // 处理上传失败
  const handleUploadError = (error) => {
    alert(error)
  }
  
  // 组件加载时获取数据
  onMounted(() => {
    console.log('组件加载，开始获取分类和图片')
    fetchCategories()
    fetchImages()
  })
  </script>
  
  <style scoped>
  .image-categories {
    height: 100vh;
    display: flex;
    flex-direction: column;
  }
  
  .toolbar {
    padding: 16px;
    background: white;
    border-bottom: 1px solid #e8e8e8;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  
  .left-actions {
    display: flex;
    gap: 16px;
    align-items: center;
  }
  
  .action-btn {
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    background: #1890ff;
    color: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
  }
  
  .search-box input {
    padding: 8px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    width: 200px;
  }
  
  .main-content {
    flex: 1;
    display: flex;
    overflow: hidden;
  }
  
  .categories-nav {
    width: 240px;
    background: white;
    border-right: 1px solid #e8e8e8;
    display: flex;
    flex-direction: column;
  }
  
  .nav-header {
    padding: 16px;
    font-weight: bold;
    border-bottom: 1px solid #e8e8e8;
  }
  
  .nav-list {
    flex: 1;
    overflow: auto;
    padding: 8px;
  }
  
  .nav-item {
    padding: 8px;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
  }
  
  .nav-item:hover {
    background: #f5f5f5;
  }
  
  .nav-item.active {
    background: #e6f7ff;
    color: #1890ff;
  }
  
  .item-name {
    flex: 1;
  }
  
  .item-count {
    padding: 2px 8px;
    background: #f0f0f0;
    border-radius: 10px;
    font-size: 12px;
  }
  
  .delete-btn {
    padding: 4px 8px;
    border: none;
    background: none;
    color: #ff4d4f;
    cursor: pointer;
    font-size: 12px;
  }
  
  .dialog-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .dialog {
    background: white;
    border-radius: 8px;
    padding: 24px;
    width: 400px;
  }
  
  .dialog h3 {
    margin: 0 0 24px 0;
  }
  
  .form-item {
    margin-bottom: 16px;
  }
  
  .form-item label {
    display: block;
    margin-bottom: 8px;
  }
  
  .form-item input,
  .form-item textarea {
    width: 100%;
    padding: 8px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
  }
  
  .dialog-footer {
    margin-top: 24px;
    display: flex;
    justify-content: flex-end;
    gap: 12px;
  }
  
  .cancel-btn,
  .confirm-btn {
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
  }
  
  .cancel-btn {
    border: 1px solid #d9d9d9;
    background: white;
  }
  
  .confirm-btn {
    border: none;
    background: #1890ff;
    color: white;
  }
  
  .images-container {
    flex: 1;
    padding: 20px;
    overflow: auto;
  }
  
  .images-header {
    margin-bottom: 20px;
    font-size: 18px;
    font-weight: bold;
  }
  
  .images-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 16px;
  }
  
  .image-item {
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
    cursor: pointer;
    transition: transform 0.2s;
  }
  
  .image-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }
  
  .image-item img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    display: block;
  }
  
  .image-info {
    padding: 8px;
  }
  
  .filename {
    display: block;
    font-size: 14px;
    color: #666;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-bottom: 4px;
  }
  
  .category {
    display: inline-block;
    padding: 2px 8px;
    background: #f0f0f0;
    border-radius: 10px;
    font-size: 12px;
    color: #666;
  }
  
  select {
    width: 100%;
    padding: 8px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
  }
  
  .primary {
    background: #1890ff;
  }
  
  .image-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 1;
    display: none;
  }
  
  .image-item:hover .image-actions {
    display: block;
  }
  
  .delete-btn {
    padding: 4px 8px;
    background: rgba(255, 0, 0, 0.7);
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s;
  }
  
  .delete-btn:hover {
    background: rgba(255, 0, 0, 0.9);
  }
  </style>